package main

import (
	"bufio"
	"fmt"
	"golang.org/x/text/encoding/simplifiedchinese"
	"io"
	"io/fs"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
)

// check file exist
func checkFile(file fs.FileInfo, path string) {
	if file.Name() == "main.go" {
		str, _ := os.Getwd()
		fmt.Println(str + "\\" + path + file.Name())
		return
	}
}

// get microservice
func getFileList(path string) {
	fs, err := ioutil.ReadDir(path)
	if err != nil {
		fmt.Println("error：", err)
		return
	} else {
		for _, file := range fs {
			if file.IsDir() {
				checkFile(file, path)
				getFileList(path + file.Name() + "\\")
			} else {
				checkFile(file, path)
			}
		}
	}
}

// strCommand is entered command
func execCommand(strCommand string) string {
	cmd := exec.Command("/bin/bash", "-c", strCommand)

	stdout, _ := cmd.StdoutPipe()
	if err := cmd.Start(); err != nil {
		fmt.Println("Execute failed when Start:" + err.Error())
		return ""
	}
	defer stdout.Close()
	outBytes, _ := ioutil.ReadAll(stdout)

	if err := cmd.Wait(); err != nil {
		fmt.Println("Execute failed when Wait:" + err.Error())
		return ""
	}
	return string(outBytes)
}

// command监控
func getOutputDirectly(name string, args ...string) (output []byte) {
	cmd := exec.Command(name, args...)
	output, err := cmd.Output() // 等到命令执行完, 一次性获取输出
	if err != nil {
		panic(err)
	}
	output, err = simplifiedchinese.GB18030.NewDecoder().Bytes(output)
	if err != nil {
		panic(err)
	}
	return
}

func getOutputContinually(name string, args ...string) <-chan struct{} {
	cmd := exec.Command(name, args...)
	closed := make(chan struct{})
	defer close(closed)

	stdoutPipe, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}
	defer stdoutPipe.Close()

	go func() {
		scanner := bufio.NewScanner(stdoutPipe)
		for scanner.Scan() { // 命令在执行的过程中, 实时地获取其输出
			data, err := simplifiedchinese.GB18030.NewDecoder().Bytes(scanner.Bytes()) // 防止乱码
			if err != nil {
				fmt.Println("transfer error with bytes:", scanner.Bytes())
				continue
			}

			fmt.Printf("%s\n", string(data))
		}
	}()

	if err := cmd.Run(); err != nil {
		panic(err)
	}
	return closed
}

func RunCommand(name string, arg ...string) error {
	cmd := exec.Command(name, arg...)
	// 命令的错误输出和标准输出都连接到同一个管道
	stdout, err := cmd.StdoutPipe()
	cmd.Stderr = cmd.Stdout

	if err != nil {
		return err
	}

	if err = cmd.Start(); err != nil {
		return err
	}
	// 从管道中实时获取输出并打印到终端
	for {
		tmp := make([]byte, 1024)
		_, err := stdout.Read(tmp)
		fmt.Print(string(tmp))
		if err != nil {
			break
		}
	}

	if err = cmd.Wait(); err != nil {
		return err
	}
	return nil
}

func main() {
	//方式一
	/*filepath.Walk("controllerMicroDemo\\microSystem", func(path string, info os.FileInfo, err error) error {
		fmt.Println(path)
		return nil
	})*/
	//方式二
	//getFileList("controllerMicroDemo\\microSystem\\") //controllerMicroDemo/microSystem
	/*strData := execCommand("ls")
	fmt.Println("ls execute finished:\n" + strData)*/

	// http 监听
	// 设置路由
	http.HandleFunc("/user", func(writer http.ResponseWriter, request *http.Request) {
		// 通过writer 将数据返回客户端
		// request包含客户发来的数据
		fmt.Println("request:", request)
		_, _ = io.WriteString(writer, `{"name":"zhangsan"}`)
	})
	http.HandleFunc("/name", func(writer http.ResponseWriter, request *http.Request) {
		fmt.Println("request:", request)
		_, _ = io.WriteString(writer, `testName`)
	})
	http.HandleFunc("/address", func(writer http.ResponseWriter, request *http.Request) {
		//fmt.Println("request:", request)
		// 不断输出, 直到结束
		//<-getOutputContinually("tree")
		go RunCommand("tracert", "www.baidu.com")
		_, _ = io.WriteString(writer, `{"address":"广州"}`)
	})
	// 设置监听
	fmt.Println("Http Server start...")
	if err := http.ListenAndServe("localhost:8089", nil); err != nil {
		fmt.Println("http start failed,err:", err)
		return
	}

}
